﻿#region Usings

using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Common.FileSystem;
using ScrumTable.UI.ViewModel;
using Brushes = System.Windows.Media.Brushes;
using Color = System.Windows.Media.Color;
using Image = System.Windows.Controls.Image;
using Point = System.Windows.Point;
using Size = System.Windows.Size;

#endregion

namespace ScrumTable.UI.View.Ink
{
    /// <summary>
    /// InkCanvasUtil
    /// </summary>
    public class InkCanvasUtil 
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------
     
        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------
 
        #endregion

        #region Methods

        public static Color GetPixelColorFromControl(Point locationPoint, Image control)
        {
            BitmapSource source = ((BitmapSource)control.Source);
            locationPoint = new Point(locationPoint.X * source.PixelWidth / control.ActualWidth, locationPoint.Y * source.PixelHeight / control.ActualHeight);
            locationPoint = new Point(Math.Min(locationPoint.X, source.PixelWidth - 1), Math.Min(locationPoint.Y, source.PixelHeight - 1));
            locationPoint = new Point(Math.Max(locationPoint.X, 1), Math.Max(locationPoint.Y, 1));

            byte[] pixels = new byte[4];
            source.CopyPixels(new Int32Rect((int)locationPoint.X, (int)locationPoint.Y, 1, 1), pixels, 4, 0);
            return Color.FromRgb(pixels[2], pixels[1], pixels[0]);

        }

        /// <summary>
        /// Gets the color of a specific pixel.
        /// </summary>
        /// <param name="locationPoint">The point from which to get a color (control relative).</param>
        /// <param name="control">control relative to the point.</param>
        /// <returns>The color of the point.</returns>
        public static Color GetPixelColor(Point locationPoint, UIElement control)
        {
            Point location = control.PointToScreen(locationPoint);
            Bitmap screenPixel = new Bitmap(1, 1);
            Graphics gfx = Graphics.FromImage(screenPixel);
            gfx.CopyFromScreen((int)location.X, (int)location.Y, 0, 0, new System.Drawing.Size(1, 1));
            var color = screenPixel.GetPixel(0, 0);
            return Color.FromRgb(color.R, color.G, color.B);

        }


        /// <summary>
        /// stores a file to as attachment to a ScrumItem
        /// </summary>
        /// <param name="fileName">name of the attachment</param>
        /// <param name="canvas">image source</param>
        /// <param name="parentScrumItem">attachment target</param>
        /// <param name="attachment">if null the new attachment gets created otherwise this attachments gets overwritten </param>
        public static AttachmentViewModel SaveImageToAttachment(string fileName, FrameworkElement canvas, IScrumItem parentScrumItem, AttachmentViewModel attachment)
        {
            var bitmapEncoder = BitmapEncoderContextFactory.CreateEncoderContext(fileName);

            string filePathRel;
            string filePathAbs;
            FileProcessor.GetFilePathAbsAndRel(out filePathRel, out filePathAbs, bitmapEncoder.Extension);

            RenderImageToFileSystem(filePathAbs, canvas, bitmapEncoder);

            attachment = attachment ?? new AttachmentViewModel(parentScrumItem.Attachments.AddNew());
            attachment.Uri = new Uri(Path.Combine(DataFolderUtil.GetTempUploadFileRelative(), filePathRel), UriKind.Relative);
            attachment.Name = bitmapEncoder.EncoderBasedFileName;

            return attachment;
        }

        private static void RenderImageToFileSystem(string filePathAbs, FrameworkElement canvas, BitmapEncoderContext bitmapEncoder)
        {
            #region Copy from canvas into RenderTargetBitmap

            RenderTargetBitmap targetImage = new RenderTargetBitmap((int)canvas.ActualWidth, (int)canvas.ActualHeight, 96d, 96d, PixelFormats.Default);
            DrawingVisual drawingVisual = new DrawingVisual();

            using (DrawingContext drawingArea = drawingVisual.RenderOpen())
            {
                VisualBrush canvasBrush = new VisualBrush(canvas);

                // draw white background
                drawingArea.DrawRectangle(Brushes.White, null, new Rect(new Point(), new Size(canvas.ActualWidth, canvas.ActualHeight)));

                // copy image from canvas into the temporary drawing visual
                drawingArea.DrawRectangle(canvasBrush, null, new Rect(new Point(), new Size(canvas.ActualWidth,canvas.ActualHeight)));
            }

            targetImage.Render(drawingVisual);

            #endregion

            #region Pass the image through the encoder and store the encoded image to FS

            bitmapEncoder.Encoder.Frames.Add(BitmapFrame.Create(targetImage));

            using (FileStream fileToSave = File.Open(filePathAbs, FileMode.Create))
            {
                bitmapEncoder.Encoder.Save(fileToSave);
            }

            #endregion
        }

        #endregion

        #region Events

        #endregion
    }
}
